Уязвимость Dirty COW

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Уязвимость Dirty COW (CVE-2016-5195, от англ. dirty + copy-on-write — копирование при записи) — серьёзная программная уязвимость в ядре Linux и Darwin[1], существующая с 2007 года и исправленная в октябре 2016 года. С её помощью локальный пользователь может повысить свои привилегии из-за ошибки состязания (гонки) в реализации механизма копирования при записи (COW) для страниц памяти, помеченных флагом Dirty bit (изменённая память).[2][3][4] На октябрь 2016 года сообщается об активной эксплуатации уязвимости при взломах серверов[4].

Технические детали

[править | править код]

Проблема возникает при многочисленном одновременном вызове системной функции madvise(MADV_DONTNEED) и записи в страницу памяти, к которой пользователь не имеет доступа на изменение[5]. Эти вызовы осуществляются из разных потоков одновременно.

При попытке записи в read-only COW-страницу памяти ядро автоматически создаёт её копию, после чего записывает данные в новую копию. Исходная страница памяти при этом остаётся нетронутой. Код уязвимого ядра Linux не проверял, завершено ли создание копии и существует ли она всё ещё, прежде чем начать запись по запрашиваемому адресу памяти. Поскольку это две последовательные инструкции, считалось маловероятным, что что-либо может «вклиниться» между ними.

Для использования эксплойта создаются два потока A и B. Системный вызов madvise(MADV_DONTNEED) в потоке A сообщает ядру о том, что программа больше никогда не собирается использовать указанную страницу памяти, поэтому ядро сразу же удаляет все копии этой страницы (но не лишает доступа к ней по прежнему адресу!). Запись в эту же страницу из потока B приводит к необходимости заново создавать её копию. При одновременном выполнении описанных выше инструкций с очень малой вероятностью может произойти ситуация, когда копия страницы удаляется сразу же после её создания, но перед операцией записи. В этот неблагоприятный момент ядро запишет данные в исходную read-only страницу памяти, а не в её копию. При многочисленном повторении запросов из разных потоков происходит гонка и маловероятное событие обязательно произойдёт, в результате чего эксплойт получает право на изменение исходной read-only страницы. Обычно процесс занимает не более нескольких секунд[6].

Необходимым условием для использования уязвимости является доступ на чтение к файлу или участку памяти. Это означает, что локальный пользователь не может напрямую перезаписать системные файлы, которые не доступны для чтения, как например /etc/shadow, что позволило бы сменить пароль суперпользователя. Однако уязвимость позволяет записать произвольный код в любой исполняемый файл, в том числе любой suid-файл. Таким образом, пользователь получает возможность «подменить» системные файлы, запускаемые им от имени root. Например, становится возможным заменить «безобидный» suid-файл ping на системный терминал, который запустится от имени root.

Несмотря на то, что ошибка повышения привилегий реализуется для локальных пользователей, удаленные злоумышленники могут использовать её в сочетании с другими эксплойтами, которые позволяют произвести удаленное выполнение непривилегированного кода. Такое сочетание приведет к полному взлому удаленной системы.[3] Использование уязвимости DirtyCOW само по себе не оставляет следов в системных журналах.[4][2]

Уязвимость получила обозначение CVE CVE-2016-5195, предварительно оценивается по шкале CVSS на 6,9-7,8 балла из 10[7]. Ошибка присутствует в ядре с 2007 года (версия 2.6.22)[2] и может быть использована на большом числе дистрибутивов, в том числе на Android[8]. Эта уязвимость стала самой длительно существовавшей критической ошибкой в ядре Linux[9]. Лишь в единичных дистрибутивах (RHEL5/6) эксплуатация одного из стандартных эксплойтов невозможна из-за отключения интерфейса «proc mem»[10]. Линус Торвальдс признался, что уже делал попытки исправления этой гонки в августе 2005 года, однако этот патч был некачественным и почти сразу был отменён из-за проблем на архитектуре S390[11].

Эксплуатацию уязвимости обнаружил исследователь безопасности Phil Oester при анализе взлома одного из администрируемых им серверов. Благодаря записи всего HTTP-трафика на протяжении нескольких лет ему удалось получить эксплойт и проанализировать его работу. Эксплойт был скомпилирован компилятором GCC версии 4.8 (вышел в 2013 году), что может свидетельствовать о том, что уязвимость успешно эксплуатируется уже на протяжении нескольких лет. Закрытое обсуждение и подготовка исправления произошли 13 октября 2016 года[12][13]. 18 октября был внесен патч, исправляющий ошибку; однако при этом Линус не указал, что данное исправление является важным и устраняет уязвимость. Подобное сокрытие важной информации и проблемы в раскрытии уязвимостей лишь усложняют жизнь пользователей и дистрибьюторов, эта практика подверглась критике в LWN[14]. 19-20 октября информация об уязвимости была опубликована RedHat; также был запущен специальный сайт[12], рассказывающий об уязвимости и предлагающий различные эксплойты, twitter-аккаунт и интернет-магазин по продаже футболок и сувениров с логотипом уязвимости.

Исправление уязвимости требует обновления ядра. Уязвимость была исправлена в ядрах версий 4.8, 4.7, 4.4 и других[15], исправление представляет собой добавление нового флага FOLL_COW (изменены 7 строк кода)[11]. Ряд дистрибутивов GNU/Linux, например, Debian, Ubuntu, RedHat и другие, уже объявили о выпуске исправленных пакетов ядра[16]. В то же время существуют многочисленные уязвимые устройства и системы на кристалле, выпуск обновлений для которых закончен производителем и может быть невозможен сторонними лицами из-за проприетарных дополнений и нарушений GPL. Например, уязвимость может использоваться для получения прав суперпользователя практически на всех Android-устройствах[17][18], с версией ОС до Android 6 включительно[19] и с ранними версиями Android 7.

В декабре 2017 был представлен вариант «Huge Dirty COW» (CVE-2017-1000405), связанный с аналогичной ошибкой в обработке больших страниц (2 МБ)[20].

Примечания

[править | править код]
  1. CVE-2022-46689 Detail. Дата обращения: 14 декабря 2023. Архивировано 14 декабря 2023 года.
  2. 1 2 3 "В ядре Linux устранена 0-day уязвимость Dirty COW, уже взятая на вооружение хакерами". xakep.ru. 2016-10-21. Архивировано 23 октября 2016. Дата обращения: 22 октября 2016.
  3. 1 2 Goodin, Dan (2016-10-20). ""Most serious" Linux privilege-escalation bug ever is under active exploit (updated)" (англ.). Ars Technica. Архивировано 10 марта 2017. Дата обращения: 21 октября 2016.
  4. 1 2 3 Vaughan-Nichols, Steven J. The Dirty Cow Linux bug: A silly name for a serious problem. Дата обращения: 21 октября 2016. Архивировано 7 мая 2021 года.
  5. Kernel Local Privilege Escalation — CVE-2016-5195 Архивная копия от 26 октября 2016 на Wayback Machine / Redhat
  6. "Dirty COW explained: Get a moooo-ve on and patch Linux root hole". The Register. 2016-10-21. Архивировано 22 октября 2016. Дата обращения: 22 октября 2016.
  7. Kernel Local Privilege Escalation - CVE-2016-5195 - Red Hat Customer Portal. Дата обращения: 21 октября 2016. Архивировано 26 октября 2016 года.
  8. Alex Hern (2016-10-21). "'Dirty Cow' Linux vulnerability found after nine years" (англ.). The Guardian. Архивировано 22 октября 2016. Дата обращения: 23 октября 2016.
  9. Security bug lifetime. CVE-2016-5195 (англ.). Kees Cook (20 октября 2016). Дата обращения: 23 октября 2016. Архивировано 23 октября 2016 года.
  10. Bug 1384344 — CVE-2016-5195 kernel: mm: privilege escalation via MAP_PRIVATE COW breakage Архивная копия от 22 октября 2016 на Wayback Machine / RedHat: «The in the wild exploit ..doesn’t work on Red Hat Enterprise Linux 5 and 6 … proc/self/mem is not writable on Red Hat Enterprise Linux 5 and 6.»
  11. 1 2 Linus Torvalds. mm: remove gup_flags FOLL_WRITE games from __get_user_pages() (англ.). 19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619. Kernel.org GIT (18 октября 2016). Дата обращения: 22 октября 2016. Архивировано 20 октября 2016 года.
  12. 1 2 Graeme Burton (2016-10-20). "Linux users urged to protect against 'Dirty COW' security flaw. All Linux users should take this seriously, says security expert" (англ.). V3. Архивировано 19 января 2018. Дата обращения: 23 октября 2016.
  13. oss-security — CVE-2016-5195 «Dirty COW» Linux kernel privilege escalation vulnerability. Дата обращения: 23 октября 2016. Архивировано 23 октября 2016 года.
  14. Dirty COW and clean commit messages Архивная копия от 4 ноября 2016 на Wayback Machine / LWN, Jonathan Corbet, October 21, 2016 (англ.)
  15. "В ядре Linux исправлена самая серьезная уязвимость повышения привилегий". securitylab.ru. 2016-10-21. Архивировано 22 октября 2016. Дата обращения: 22 октября 2016.
  16. CVE-2016-5195. Дата обращения: 21 октября 2016. Архивировано 21 октября 2016 года.
  17. "Android phones rooted by "most serious" Linux escalation bug ever". Ars Technica (англ.). 2016-10-24. Архивировано 29 января 2017. Дата обращения: 25 октября 2016. {{cite news}}: Указан более чем один параметр |accessdate= and |access-date= (справка)
  18. Every Android device potentially vulnerable to «most serious» Linux escalation attack, ever / Boing Boing. Дата обращения: 25 октября 2016. Архивировано 26 октября 2016 года.
  19. Dirty COW затрагивает не только Linux, но и все версии Android. Дата обращения: 25 октября 2016. Архивировано 26 октября 2016 года.
  20. Tom Spring. Flaw Found In Dirty COW Patch. threat post (1 декабря 2017). Дата обращения: 18 декабря 2017. Архивировано 7 февраля 2018 года. (en Архивная копия от 8 декабря 2017 на Wayback Machine)